Skip to content

Funding signed event#3024

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
jbesraa:funding-signed-event
Jul 22, 2024
Merged

Funding signed event#3024
tnull merged 1 commit into
lightningdevkit:mainfrom
jbesraa:funding-signed-event

Conversation

@jbesraa

@jbesraa jbesraa commented Apr 25, 2024

Copy link
Copy Markdown
Contributor

resolves #3023 and #3022

@codecov-commenter

codecov-commenter commented Apr 25, 2024

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 80.95238% with 32 lines in your changes missing coverage. Please review.

Project coverage is 89.82%. Comparing base (bfc20f8) to head (8403755).

Files Patch % Lines
lightning/src/events/mod.rs 0.00% 20 Missing ⚠️
lightning/src/ln/channelmanager.rs 87.17% 6 Missing and 4 partials ⚠️
lightning/src/ln/functional_tests.rs 95.65% 2 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #3024    +/-   ##
========================================
  Coverage   89.81%   89.82%            
========================================
  Files         121      121            
  Lines       99515    99657   +142     
  Branches    99515    99657   +142     
========================================
+ Hits        89381    89518   +137     
- Misses       7519     7530    +11     
+ Partials     2615     2609     -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment thread lightning/src/events/mod.rs Outdated
/// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
user_channel_id: u128,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should give the funding tx to broadcast

@jbesraa
jbesraa force-pushed the funding-signed-event branch 3 times, most recently from e9ffefc to d48453a Compare April 29, 2024 09:21
@jbesraa
jbesraa marked this pull request as ready for review April 29, 2024 11:51
Comment thread lightning/src/ln/channelmanager.rs Outdated
Comment thread lightning/src/ln/channel.rs Outdated
@jbesraa
jbesraa force-pushed the funding-signed-event branch 2 times, most recently from cb5e32f to 20313c8 Compare April 29, 2024 11:59
Comment thread lightning/src/ln/functional_tests.rs Outdated
Comment thread lightning/src/util/config.rs Outdated
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
pub accept_mpp_keysend: bool,
/// broadcast funding transaction manually
pub manually_broadcast_outbound_channels: bool,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is it best to do this via a config or via a different method to pass LDK the funding transaction? A config seems to imply people might want to just turn this on, but really its a totally differnet flow, and maybe thus makes sense as a different method since it'll change the programming entirely?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok ill give that a try to see how that works.

What do you think about the next event after FundingSigned? In the current implementation its going from FundingSigned to ChannelReady ie skips the ChannelPending. I did that because in the code ChannelPending = "funding is ready and signed, just wait for confirmations", but that is not accurate for all cases. in payjoin scenario we never really know that the funding is fully signed and broadcasted.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we should probably keep ChannelPending, I think - its pending from the lightning POV, just something else is dealing with broadcasting.

Comment thread lightning/src/ln/channel.rs Outdated
@jbesraa
jbesraa force-pushed the funding-signed-event branch 2 times, most recently from 5f7cf6c to 1aa96df Compare May 31, 2024 10:42
@jbesraa

jbesraa commented May 31, 2024

Copy link
Copy Markdown
Contributor Author

Done few things:

  1. CherryP Add unsafe_funding_transaction_generated #3056 here
  2. Removed FUNDING_SIGNED channel state
  3. Removed config manually_broadcast_.. argument

Yet to do:

  1. Complete the docs
  2. Fix CI
  3. Improve/fix naming around the new property in ChannelContext

@jbesraa
jbesraa force-pushed the funding-signed-event branch 5 times, most recently from bed2ba6 to b3d033d Compare June 3, 2024 10:31
@jbesraa

jbesraa commented Jun 3, 2024

Copy link
Copy Markdown
Contributor Author

@TheBlueMatt @benthecarman this is ready for review

@tnull tnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did an intial pass.

Comment thread lightning/src/events/mod.rs Outdated
///
/// Upon receiving this event, it is your responsibility to broadcast the funding transaction.
///
/// [`ChannelManager::unsafe_manual_funding_transaction_generated`]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: These references need to live on a single line each, I believe.

Comment thread lightning/src/events/mod.rs Outdated
/// crate::ln::channelmanager::ChannelManager::unsafe_manual_funding_transaction_generated
/// [`ChannelManager::funding_transaction_generated`]:
/// crate::ln::channelmanager::ChannelManager::funding_transaction_generated
FundingSigned {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also include the counterparty_node_id and former_temporary_channel_id here?

Comment thread lightning/src/events/mod.rs Outdated
/// network. For 0conf channels it will be immediately followed by the corresponding
/// [`Event::ChannelReady`] event.
///
/// [`ChannelManager::unsafe_manual_funding_transaction_generated`]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Same as above: move to a single line.

Comment thread lightning/src/events/mod.rs Outdated
f()
},
41u8 => {
let mut channel_id = ChannelId::new_zero();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use RequiredWrapper(None) instead of initializing these defaults.

Comment thread lightning/src/ln/channel.rs Outdated
/// The funding transaction can be accessed through the [`Event::FundingSigned`] event.
///
/// [`Event::FundingSigned`]: crate::events::Event::FundingSigned
manually_broadcast_outbound_channels: Option<()>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this an Option<()> rather than a bool? Also, given this is a flag indicating whether we broadcast the transaction, should this start with did_ or is_?

@jbesraa jbesraa Jun 3, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Option<()> is mainly because other variables like is_batch_funding and local_initiated_shutdown are defined with Option so I was trying to follow that. I was sure it saves a byte or two but it seems it doesnt. happy to change it back to bool

Comment thread lightning/src/ln/channel.rs Outdated
pub fn is_funding_broadcast(&self) -> bool {
!self.channel_state.is_pre_funded_state() &&
!matches!(self.channel_state, ChannelState::AwaitingChannelReady(flags) if flags.is_set(AwaitingChannelReadyFlags::WAITING_FOR_BATCH))
!self.channel_state.is_pre_funded_state()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Remove the superfluous indent. Generally, since nothing seems to have actually changed here, might be preferable to not touch this code at all?

Comment thread lightning/src/ln/channel.rs Outdated
(matches!(self.context.channel_state, ChannelState::AwaitingChannelReady(flags) if !flags.is_set(AwaitingChannelReadyFlags::WAITING_FOR_BATCH)) ||
matches!(self.context.channel_state, ChannelState::ChannelReady(_)))
{
if self.context.manually_broadcast_outbound_channels.is_none()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: if nothing actually changed, it would be preferable to not touch it, or do the reformatting in a separate commit.

Comment thread lightning/src/ln/channelmanager.rs Outdated
}
if result != Ok(()) { return result; }

return self.batch_funding_transaction_generated_intern(temporary_channels, funding_transaction, false);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could just avoid the above if and do

Suggested change
return self.batch_funding_transaction_generated_intern(temporary_channels, funding_transaction, false);
result.and(self.batch_funding_transaction_generated_intern(temporary_channels, funding_transaction, false))

here.

Comment thread lightning/src/ln/channel.rs Outdated
// Checks whether we should emit a `ChannelPending` event.
pub(crate) fn should_emit_channel_pending_event(&mut self) -> bool {
self.is_funding_broadcast() && !self.channel_pending_event_emitted
self.is_funding_broadcast() && !self.channel_pending_event_emitted && self.manually_broadcast_outbound_channels.is_none()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, any way we can keep ChannelPending?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have two options here:

  1. Let the user tell us they broadcasted the transaction and as a result we emit ChannelPending
  2. Track the chain and check when the transaction is in the mempool and emit ChannelPending

First option is not always doable from the user perspective, for example in payjoin scenario you dont really know when the tx will be broadcasted. wdyt?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also just generate it when we generate the FundingSigned event, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be the easiest if we are comfortable emitting both events simultaneously

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we would, yes.

Comment thread lightning/src/events/mod.rs Outdated
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
user_channel_id: u128,
},
/// Used to indicate that the counterparty node has sent us `funding_signed` message but we are

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great for people who work on the lightning protocol, but we try to keep our docs understandable for those who do not as well. Instead, we should phrase simply as "the counterparty has provided the signature(s) required to recover our funds if they go offline and the funding transaction is now broadcastable" or so.

Comment thread lightning/src/events/mod.rs Outdated
/// crate::ln::channelmanager::ChannelManager::unsafe_manual_funding_transaction_generated
/// [`ChannelManager::funding_transaction_generated`]:
/// crate::ln::channelmanager::ChannelManager::funding_transaction_generated
FundingSigned {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FundingSigned is a reference to a lightning-internal name, but isn't reflective of what has happened (the funding transaction itself was not signed, rather the first commitment transaction was) nor what has changed from the user's perspective (the funding transaction is now broadcastable).

Comment thread lightning/src/ln/channelmanager.rs Outdated
}
macro_rules! emit_funding_signed_event {
($locked_events: expr, $channel: expr) => {
let should_emit = $channel.context.should_emit_funding_signed_event();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly, like with actual broadcasting, we need to not emit the event until the channelmonitor update that has the new signature gets written to disk (as otherwise its not, actually, safe to broadcast yet). In general, there's a lot of machinery here to duplicate what we do with the funding transaction broadcast...ISTM we could better simplify this code by just checking if the channel is "manual broadcast" whenever we'd otherwise broadcast the funding tx and convert to an event (if relevant).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following your suggestion above with emitting both events simultaneously, could we have the same should_emit_..(roughly, excluding the respective variable is_emitted..) function for FundingSigned and ChannelPending events?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, but it certainly seems to match up tighter with when LDK decides to broadcast, rather than when we decide to release the pending event.

@jbesraa
jbesraa force-pushed the funding-signed-event branch 4 times, most recently from 0540f52 to b21c02c Compare June 4, 2024 11:18

@tnull tnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically LGTM, just a few nits.

Comment thread lightning/src/events/mod.rs Outdated
channel_id: ChannelId,
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
/// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
/// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
/// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
/// [`UserConfig::manually_accept_inbound_channels`] config flag is set to `true`. Otherwise

Comment thread lightning/src/ln/channel.rs Outdated
counterparty_forwarding_info: Option<CounterpartyForwardingInfo>,

pub(crate) channel_transaction_parameters: ChannelTransactionParameters,
/// The transaction which funds this channel. Note that for manually-funded channels(i.e,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
/// The transaction which funds this channel. Note that for manually-funded channels(i.e,
/// The transaction which funds this channel. Note that for manually-funded channels (i.e.,

Comment thread lightning/src/ln/channel.rs Outdated
/// This flag indicates that it is the user's responsibility to validated and broadcast the
/// funding transaction.
///
/// [`Event::FundingTxBroadcastSafe`]: crate::events::Event::FundingTxBroadcastSafe

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop unused doc link.

Suggested change
/// [`Event::FundingTxBroadcastSafe`]: crate::events::Event::FundingTxBroadcastSafe

Comment thread lightning/src/ln/channel.rs Outdated
(45, cur_holder_commitment_point, option),
(47, next_holder_commitment_point, option),
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
(51, is_manual_broadcast, option),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add // Added in .. comments for these fields, like the ones above?

Comment thread lightning/src/ln/channelmanager.rs Outdated
user_channel_id: $channel.context.get_user_id(),
funding_txo: $funding_txo,
counterparty_node_id: $channel.context.get_counterparty_node_id(),
former_temporary_channel_id: $channel.context.temporary_channel_id().expect("Unreachable: FundingTxBroadcastSafe event feature added to channel establishment process in LDK v0.124.0 where this should never be None."),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add newline before .expect

Comment thread lightning/src/ln/channelmanager.rs Outdated
}


/// Unsafe: This method does not check the validatiy of the provided output. It is the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Unsafe: This method does not check the validatiy of the provided output. It is the
/// **Unsafe**: This method does not check the validity of the provided output. It is the

@jbesraa
jbesraa force-pushed the funding-signed-event branch from dad9947 to d0e779f Compare June 19, 2024 11:59
Comment thread lightning/src/events/mod.rs Outdated
Comment thread lightning/src/ln/channelmanager.rs Outdated
emit_funding_tx_broadcast_safe_event!(pending_events, channel, funding_txo.into_bitcoin_outpoint())
},
None => {
log_error!(logger, "Channel resumed without a funding txo, this should never happen!");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can safely debug_assert!(false); here :)

internal_create_funding_transaction(node, expected_counterparty_node_id, expected_chan_value, expected_user_chan_id, true)
}

pub fn create_funding_tx_without_witness_data<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the method no longer even takes a full tx this seems like overkill :). It can now be deduced entirely from the API itself that the ChannelManager cannot possibly test for witnesses.

Comment thread lightning/src/ln/channelmanager.rs Outdated
/// broadcasted and you are expected to broadcast it manually when receiving the
/// [`Event::FundingTxBroadcastSafe`] event.
///
/// Returns an [`APIError::APIMisuseError`] if no output was found which matches the parameters

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't happen anymore ;)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line still needs removing.

Comment thread lightning/src/ln/channelmanager.rs Outdated
/// Returns [`APIError::ChannelUnavailable`] if a funding transaction has already been provided
/// for the channel or if the channel has been closed as indicated by [`Event::ChannelClosed`].
///
/// May panic if the output found in the funding transaction is duplicative with some other

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// May panic if the output found in the funding transaction is duplicative with some other
/// May panic if the funding output is duplicative with some other

Comment thread lightning/src/ln/channelmanager.rs Outdated
}


/// **Unsafe**: This method does not check the validity of the provided output. It is the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we should say what that validity requirement is. Specifically its very easy for a user to not check that inputs are segwit, so we should mention that explicitly imo.

@jbesraa
jbesraa force-pushed the funding-signed-event branch 2 times, most recently from e61909f to d359dab Compare June 20, 2024 09:24
@jbesraa

jbesraa commented Jun 20, 2024

Copy link
Copy Markdown
Contributor Author

@TheBlueMatt please see last commit for changes.

I am not sure now we still need funding_transaction_generated_intern and funding_transaction_generated ? wdyt?

@TheBlueMatt TheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure now we still need funding_transaction_generated_intern and funding_transaction_generated ? wdyt?

Not quite sure what your question is?

Comment thread lightning/src/ln/channelmanager.rs Outdated


/// **Unsafe**: This method does not check the validity of the provided output. It is the
/// caller's responsibility to ensure that. Its important to validate you are using SegWit

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads as if you're supposed to check that the funding output is segwit, which is true but users shouldn't need to worry too much about it unless they screw up really bad. Instead, they need to check that all inputs are segwit.

@jbesraa
jbesraa force-pushed the funding-signed-event branch 2 times, most recently from a563480 to 06ba332 Compare July 1, 2024 06:43
TheBlueMatt
TheBlueMatt previously approved these changes Jul 8, 2024

@TheBlueMatt TheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo a few nits.

Comment thread lightning/src/ln/channelmanager.rs Outdated


/// **Unsafe**: This method does not validate the spent output. It is the caller's
/// responsibility to ensure the spent output are SegWit, as well as making sure the funding

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// responsibility to ensure the spent output are SegWit, as well as making sure the funding
/// responsibility to ensure the spent outputs are SegWit, as well as making sure the funding

Comment thread lightning/src/ln/channelmanager.rs Outdated
/// broadcasted and you are expected to broadcast it manually when receiving the
/// [`Event::FundingTxBroadcastSafe`] event.
///
/// Returns an [`APIError::APIMisuseError`] if no output was found which matches the parameters

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line still needs removing.

Comment thread lightning/src/ln/channelmanager.rs Outdated
err: "Transaction had more than 2^16 outputs, which is not supported".to_owned()
}));
}
{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you can drop the unnecessary scope here if you want now.

@jbesraa

jbesraa commented Jul 8, 2024

Copy link
Copy Markdown
Contributor Author

@TheBlueMatt Addressed all comments

The `FundingTxBroadcastSafe` event indicates that we have received
`funding_signed` message from our counterparty and that you should
broadcast the funding transaction.

This event is only emitted if upon generating the funding transaction
you call `ChannelManager::unsafe_manual_funding_transaction_generated`
that will emit this event instead of `ChannelPending` event.

`ChannelManager::unsafe_manual_funding_transaction_generated` wont check
if the funding transaction is signed, those its unsafe. It is manual
because you are responsibile on broadcasting the transaction once the
event is received.
@jbesraa
jbesraa force-pushed the funding-signed-event branch from 150e748 to 8403755 Compare July 8, 2024 17:10

@TheBlueMatt TheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, noticed one more issue, but we can address it in a followup in the same release cause this PR has gotten somewhat long in the tooth.


pub(crate) channel_transaction_parameters: ChannelTransactionParameters,
/// The transaction which funds this channel. Note that for manually-funded channels (i.e.,
/// is_manual_broadcast is true) this will be a dummy empty transaction.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, one more issue here, the DiscardFunding event will now expose the dummy transaction here. We should hide that by adding an enum and including the funding OutPoint there instead.

@tnull

tnull commented Jul 22, 2024

Copy link
Copy Markdown
Contributor

Excuse the delay here, landing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add FundingSigned event

5 participants